package com.xiehua.task.server;

import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.routing.BalancingPool;
import com.typesafe.config.ConfigFactory;
import com.xiehua.task.actor.*;
import com.xiehua.task.actor.cmd.Cmd;
import com.xiehua.task.job.Timer;
import com.xiehua.task.monitor.Monitor;
import com.xiehua.task.prop.XiehuaConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.server.AioServer;
import org.tio.server.ServerGroupContext;
import org.tio.server.intf.ServerAioHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ServerApp {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerApp.class);

    /**
     * 启动程序入口
     * @throws InterruptedException
     */
    public static void main(String[] args) throws Exception {
        Map<String,String> configMap = XiehuaConfig.getInstance();
        ServerAioHandler aioHandler = new ServerHandler();
        ServerGroupContext serverGroupContext = new ServerGroupContext("xiehua-task-server", aioHandler, new ServerListener());
        serverGroupContext.setHeartbeatTimeout(Integer.parseInt(configMap.get(XiehuaConfig.KEY_SERVER_TIMEOUT)));
        //init aio server
        AioServer aioServer = new AioServer(serverGroupContext);
        //start server
        aioServer.start(configMap.get(XiehuaConfig.KEY_SERVER_HOST), Integer.parseInt(configMap.get(XiehuaConfig.KEY_SERVER_PORT)));
        //init actor system
        ActorSystem system = ActorSystem.create("xiehua_task_server_actors_sys", ConfigFactory.load("akka.conf"));
        system.actorOf(new BalancingPool(3).props(Props.create(TaskNotifyActor.class,serverGroupContext)),"TaskNotifyActor");
        ActorRef taskReadyActor = system.actorOf(new BalancingPool(3).props(Props.create(TaskReadyActor.class)),"TaskReadyActor");
        ActorRef emailActor = system.actorOf(new BalancingPool(3).props(Props.create(EmailActor.class)),"EmailActor");
        ActorRef taskDisposeActor = system.actorOf(new BalancingPool(3).props(Props.create(TaskDisposeActor.class)),"TaskDisposeActor");
        // 订阅
//        system.eventStream().subscribe(taskDisposeActor , Cmd.class);
        //init timer
        Timer timer = new Timer(taskReadyActor);
        timer.start();
        //init monitor
        List<Thread> monitoredThread = new ArrayList<>();
        monitoredThread.add(timer);
        Monitor monitor = new Monitor(monitoredThread,emailActor);
        monitor.start();
    }
}
